/* Abstract class that provides some basic properties
 * and functions to an object
 */
 
#pragma once

#include <ogrevector3.h>
#include "IObjectManager.h"
#include "PlayerObject.h"
#include "AutoObject.h"
#include "StationaryObject.h"
#include "Wall3D.h"


class ObjectManager : public IObjectManager
{
	friend class GameEngine;
public:
	ObjectManager();
	~ObjectManager();

	//Inherited from IGameManager
	void Initialize();
	void UpdateStarted(const Ogre::FrameEvent &gameTime);
	void UpdateEnded(const Ogre::FrameEvent &gameTime);
	void Cleanup();

	//Inherited from IObjectManager
	void AddPlayerObject(double xpos, double ypos, double zpos);
	void RemovePlayerObject();
    IMovingObject* GetPlayerObject(int id);
	std::vector<IMovingObject*>* GetPlayerList();

	void AddStationaryObject(double xpos, double ypos, double zpos);
	void RemoveStationaryObject(int id);
	IObject* GetStationaryObject(int id);
	std::vector<IObject*>* GetStationaryList();

	void AddAutonomousObject(double xpos, double ypos, double zpos);
	void RemoveAutonomousObject();
	IMovingObject* GetAutonomousObject(int id);
	std::vector<IMovingObject*>* GetAutonomousList();

    void AddWall(Ogre::Vector3 A, Ogre::Vector3 B, Ogre::Vector3 C, Ogre::Vector3 D);
    void RemoveWall(int id);
    IWall* GetWall(int id);
    std::vector<IWall*>* GetWallList();

	int GetPlayerObjectCount();
	int GetAutonomousObjectCount();
	int GetStationaryObjectCount();
	int GetWallCount();

	bool LineIntersection(Ogre::Vector3 A, Ogre::Vector3 B, Ogre::Vector3 C, 
							Ogre::Vector3 D, double &dist, Ogre::Vector3 &point);

	static IObjectManager* getSingleton()
	{
		if(!_objectManager)
		{
			_objectManager = new ObjectManager();
		}
		return _objectManager;
	}

	//Only in ObjectManager class
	bool exsitsPlayer;		
	bool exsitsAutonomous;
	bool exsitsStationary;
	bool exsitsWall;

protected:
	static IObjectManager* _objectManager;

private:
	std::vector<IMovingObject*>* _playerObjectList;
	std::vector<IMovingObject*>* _autoObjectList;
	std::vector<IObject*>* _stationaryObjectList;
	std::vector<IWall*>* _wallList;
	int _playerObjectCount;
	int _autonomousObjectCount;
	int _stationaryObjectCount;
	int _wallCount;
};